"""
物性计算模块

本模块使用CoolProp库计算水和蒸汽的物性参数，包括：
- 密度
- 粘度
- 导热系数
- 比热容
- 焓
- 饱和温度/压力
- 表面张力

作者：[您的名字]
日期：[创建日期]
"""

from typing import Dict, Union
import numpy as np
from CoolProp.CoolProp import PropsSI

class FluidProperties:
    """流体物性计算类"""
    
    def __init__(self):
        """初始化物性计算器"""
        self.fluid = "Water"  # 工质为水
        
        # 缓存一些常用的临界点参数
        self.p_crit = PropsSI("PCRIT", self.fluid)  # 临界压力
        self.T_crit = PropsSI("TCRIT", self.fluid)  # 临界温度
        self.rho_crit = PropsSI("RHOCRIT", self.fluid)  # 临界密度
        
    def get_saturation_properties(self, P: float) -> Dict[str, float]:
        """
        获取给定压力下的饱和物性
        
        参数:
            P: float, 压力 [Pa]
            
        返回:
            Dict[str, float]: 包含饱和物性的字典
        """
        try:
            # 饱和温度
            T_sat = PropsSI("T", "P", P, "Q", 0, self.fluid)
            
            # 饱和液相物性
            rho_l = PropsSI("D", "P", P, "Q", 0, self.fluid)  # 密度
            mu_l = PropsSI("V", "P", P, "Q", 0, self.fluid)   # 动力粘度
            k_l = PropsSI("L", "P", P, "Q", 0, self.fluid)    # 导热系数
            cp_l = PropsSI("C", "P", P, "Q", 0, self.fluid)   # 定压比热
            h_l = PropsSI("H", "P", P, "Q", 0, self.fluid)    # 比焓
            
            # 饱和气相物性
            rho_v = PropsSI("D", "P", P, "Q", 1, self.fluid)  # 密度
            mu_v = PropsSI("V", "P", P, "Q", 1, self.fluid)   # 动力粘度
            k_v = PropsSI("L", "P", P, "Q", 1, self.fluid)    # 导热系数
            cp_v = PropsSI("C", "P", P, "Q", 1, self.fluid)   # 定压比热
            h_v = PropsSI("H", "P", P, "Q", 1, self.fluid)    # 比焓
            
            # 表面张力
            sigma = PropsSI("I", "P", P, "Q", 0, self.fluid)
            
            return {
                "T_sat": T_sat,
                "liquid": {
                    "density": rho_l,
                    "viscosity": mu_l,
                    "conductivity": k_l,
                    "specific_heat": cp_l,
                    "enthalpy": h_l
                },
                "vapor": {
                    "density": rho_v,
                    "viscosity": mu_v,
                    "conductivity": k_v,
                    "specific_heat": cp_v,
                    "enthalpy": h_v
                },
                "surface_tension": sigma
            }
            
        except Exception as e:
            print(f"计算饱和物性时出错: {str(e)}")
            return None
            
    def get_liquid_properties(self, P: float, T: float) -> Dict[str, float]:
        """
        获取给定压力和温度下的液相物性
        
        参数:
            P: float, 压力 [Pa]
            T: float, 温度 [K]
            
        返回:
            Dict[str, float]: 包含液相物性的字典
        """
        try:
            # 检查是否在液相区
            h = PropsSI("H", "P", P, "T", T, self.fluid)
            h_sat_l = PropsSI("H", "P", P, "Q", 0, self.fluid)
            
            if h > h_sat_l:
                print(f"警告：给定点 (P={P} Pa, T={T} K) 不在液相区")
            
            # 计算物性
            rho = PropsSI("D", "P", P, "T", T, self.fluid)  # 密度
            mu = PropsSI("V", "P", P, "T", T, self.fluid)   # 动力粘度
            k = PropsSI("L", "P", P, "T", T, self.fluid)    # 导热系数
            cp = PropsSI("C", "P", P, "T", T, self.fluid)   # 定压比热
            
            return {
                "density": rho,
                "viscosity": mu,
                "conductivity": k,
                "specific_heat": cp,
                "enthalpy": h
            }
            
        except Exception as e:
            print(f"计算液相物性时出错: {str(e)}")
            return None
            
    def get_vapor_properties(self, P: float, T: float) -> Dict[str, float]:
        """
        获取给定压力和温度下的气相物性
        
        参数:
            P: float, 压力 [Pa]
            T: float, 温度 [K]
            
        返回:
            Dict[str, float]: 包含气相物性的字典
        """
        try:
            # 检查是否在气相区
            h = PropsSI("H", "P", P, "T", T, self.fluid)
            h_sat_v = PropsSI("H", "P", P, "Q", 1, self.fluid)
            
            if h < h_sat_v:
                print(f"警告：给定点 (P={P} Pa, T={T} K) 不在气相区")
            
            # 计算物性
            rho = PropsSI("D", "P", P, "T", T, self.fluid)  # 密度
            mu = PropsSI("V", "P", P, "T", T, self.fluid)   # 动力粘度
            k = PropsSI("L", "P", P, "T", T, self.fluid)    # 导热系数
            cp = PropsSI("C", "P", P, "T", T, self.fluid)   # 定压比热
            
            return {
                "density": rho,
                "viscosity": mu,
                "conductivity": k,
                "specific_heat": cp,
                "enthalpy": h
            }
            
        except Exception as e:
            print(f"计算气相物性时出错: {str(e)}")
            return None
    
    def get_surface_tension(self, T: float) -> float:
        """
        计算给定温度下的表面张力
        
        参数:
            T: float, 温度 [K]
            
        返回:
            float: 表面张力 [N/m]
        """
        try:
            # 在给定温度下计算饱和压力
            P_sat = PropsSI("P", "T", T, "Q", 0, self.fluid)
            
            # 计算表面张力
            sigma = PropsSI("I", "T", T, "Q", 0, self.fluid)
            
            return sigma
            
        except Exception as e:
            print(f"计算表面张力时出错: {str(e)}")
            return None
    
    def get_phase_change_properties(self, P: float) -> Dict[str, float]:
        """
        计算相变相关的物性
        
        参数:
            P: float, 压力 [Pa]
            
        返回:
            Dict[str, float]: 包含相变物性的字典
        """
        try:
            # 饱和温度
            T_sat = PropsSI("T", "P", P, "Q", 0, self.fluid)
            
            # 汽化潜热
            h_l = PropsSI("H", "P", P, "Q", 0, self.fluid)
            h_v = PropsSI("H", "P", P, "Q", 1, self.fluid)
            h_fg = h_v - h_l
            
            # 表面张力
            sigma = PropsSI("I", "P", P, "Q", 0, self.fluid)
            
            return {
                "T_sat": T_sat,
                "h_fg": h_fg,
                "surface_tension": sigma
            }
            
        except Exception as e:
            print(f"计算相变物性时出错: {str(e)}")
            return None 